package org.zavgame.ejb;

import java.util.LinkedList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

@Stateless
public class Players implements PlayerInterface
{

   @PersistenceContext(unitName = "player-unit")
   private EntityManager entityManager;
   
   /**
    * {@inheritDoc} 
    */
   public PlayerResponse balanceUpdate(PlayerRequest request) throws Exception
   {

      int balanceVersion = 1;
      int balance = request.getBalanceChange();
      Player p = getLatest(request.getUsername());
      if (p != null)
      {
         balanceVersion += p.getBalanceVersion();
         balance += p.getBalance();
      }
      Player player = new Player(request.getUsername(), balanceVersion, balance);
      entityManager.persist(player);

      PlayerResponse response = new PlayerResponse();
      response.setTransactionId(request.getTransactionId());
      response.setErrorCode(200); // HTTP 200 - OK
      response.setBalanceVersion(balanceVersion);
      response.setBalanceChange(request.getBalanceChange());
      response.setBalanceAfterChange(balance);

      return response;

   }

   /**
    * {@inheritDoc} 
    */
   public PlayerResponse getBalance(PlayerRequest request)
   {
      Player p = getLatest(request.getUsername());
      if (p != null)
      {
         PlayerResponse response = new PlayerResponse();
         response.setTransactionId(request.getTransactionId());
         response.setErrorCode(200); // HTTP 200 - OK
         response.setBalanceVersion(p.getBalanceVersion());
         response.setBalanceChange(request.getBalanceChange());
         response.setBalanceAfterChange(p.getBalance());
         return response;
      }
      else
      {
         // there is no player with the provided username
         PlayerResponse response = new PlayerResponse();
         response.setTransactionId(request.getTransactionId());
         response.setErrorCode(404); // HTTP 404 - Not Found
         response.setBalanceVersion(0);
         response.setBalanceChange(0);
         response.setBalanceAfterChange(0);
         return response;
      }
   }

   /**
    * {@inheritDoc} 
    */
   public List<PlayerResponse> getPlayerHistory(PlayerRequest request)
   {
      Query query = entityManager.createNamedQuery("player.query").setParameter("username", request.getUsername());
      List<Player> list = (List<Player>)query.getResultList();
      if (list != null && list.size() > 0)
      {
         List<PlayerResponse> result = new LinkedList<PlayerResponse>();
         for (Player player : list)
         {
            result.add(createPlayerResponse(player, request.getTransactionId()));
         }
         return result;
      }
      else
      {
         // there is no player with the provided username
         return null;
      }
   }

   /**
    * To create PlayerResponse for the list of history.
    * 
    * @param player
    * @param transactionId
    * @return
    */
   private PlayerResponse createPlayerResponse(Player player, String transactionId)
   {
      PlayerResponse response = new PlayerResponse();
      response.setTransactionId(transactionId);
      response.setErrorCode(200); // HTTP 200 - OK
      response.setBalanceVersion(player.getBalanceVersion());
      response.setBalanceChange(0);
      response.setBalanceAfterChange(player.getBalance());
      return response;
   }

   /**
    * Get latest Player data from the storage.
    * @param username
    * @return
    */
   private Player getLatest(String username)
   {
      Query query = entityManager.createNamedQuery("player.query").setParameter("username", username).setMaxResults(1);
      List<Player> pList = (List<Player>)query.getResultList();
      if (pList != null && pList.size() > 0)
      {
         return pList.get(0);
      }
      else
      {
         // there is no player with the provided username
         return null;
      }
   }

}
